<script setup>
import { useRouter } from 'vue-router';
import authService from "@/services/auth.service";
import { useAuthStore } from '@/stores/auth';
import { ElMessage, ElForm, ElFormItem, ElInput, ElButton, ElCheckbox } from 'element-plus';
import { CircleCheck, Lock, User } from '@element-plus/icons-vue';
import { onBeforeUnmount, onMounted, reactive, ref } from 'vue';
import { AxiosError } from 'axios';
import bg from "@/assets/login/bg.png";
import personalCenterService from '@/services/personal-center.service';
import { Search, Refresh, Plus, Edit, Delete, View, Upload, Download, Share, Close } from "@element-plus/icons-vue";

const router = useRouter();
const authStore = useAuthStore();

const entity = ref({});
const rememberMe = ref(true);
const REMEMBER_ME_KEY = "fast_alden_remember_me";
const formRef = ref();
const loading = ref(false);
const verifyCodeUrl = ref("");

const rules = reactive({
    username: [
        {
            required: true,
            message: '请输入用户名',
            trigger: 'blur'
        }
    ],
    password: [
        {
            validator: (rule, value, callback) => {
                if (!value) {
                    callback(new Error("请输入密码"));
                } else {
                    callback();
                }
            },
            trigger: "blur"
        }
    ],
    verifyCode: [
        {
            required: true,
            message: '请输入验证码',
            trigger: 'blur'
        },
    ],
});

const login = async () => {
    const formEl = formRef.value;
    loading.value = true;
    if (!formEl) {
        loading.value = false;
        return;
    }
    await formEl.validate(async (valid, fields) => {
        if (valid) {
            try {
                const res = await authService.login(entity.value);
                const authData = res.data.data;
                if (authData && authData.token) {
                    const { token } = authData;
                    authStore.authenticate({ token });
                    const userProfile = await personalCenterService.retrieve();
                    authStore.setUserProfile(userProfile);

                    // warning: 此方式直接将用户名密码明文存入localStorage，并不安全
                    // todo：寻找更合理方式实现“记住我”
                    if (rememberMe.value) {
                        localStorage.setItem(REMEMBER_ME_KEY, JSON.stringify({
                            username: entity.value.username,
                            password: entity.value.password,
                        }));
                    } else {
                        localStorage.removeItem(REMEMBER_ME_KEY);
                    }

                    ElMessage({ message: "登录成功", type: "success" });
                    router.push("/");
                }
            } catch (err) {
                if (err instanceof AxiosError) {
                    const msg = err.response?.data?.message || err.message;
                    ElMessage({ message: msg, type: "error" });
                }
                updateVerifyCode();
                throw err;
            } finally {
                loading.value = false;
            }
        } else {
            loading.value = false;
            return fields;
        }
    });
};

const updateVerifyCode = async () => {
    const res = await authService.getVerifyCode();
    verifyCodeUrl.value = `${res.data.data?.image}`;
    entity.value.verifyCodeKey = res.data.data?.key;
}

/** 使用公共函数，避免`removeEventListener`失效 */
function onkeypress({ code }) {
    if (code === "Enter" || code === "NumpadEnter") {
        login();
    }
}

const load = async () => {
    const tmp = localStorage.getItem(REMEMBER_ME_KEY);
    if (tmp) {
        const e = JSON.parse(tmp);
        entity.value.username = e.username;
        entity.value.password = e.password;
    }
}

onMounted(async () => {
    window.document.addEventListener("keypress", onkeypress);

    updateVerifyCode();

    load();
});

onBeforeUnmount(() => {
    window.document.removeEventListener("keypress", onkeypress);
});

</script>

<template>
    <img class="login-bg" :src="bg" />
    <div class="login-container">
        <div class="login-box">
            <ElForm class="login-form" ref="formRef" :model="entity" :rules="rules" size="large">
                <h3 class="title">快安后台管理系统</h3>
                <ElFormItem prop="username">
                    <ElInput clearable v-model="entity.username" placeholder="用户名/手机号/邮箱" :prefix-icon="User" />
                </ElFormItem>

                <ElFormItem prop="password">
                    <ElInput clearable show-password v-model="entity.password" placeholder="密码" :prefix-icon="Lock" />
                </ElFormItem>

                <ElFormItem class="verify-code-row" prop="verifyCode">
                    <ElInput clearable v-model="entity.verifyCode" placeholder="验证码" :prefix-icon="CircleCheck">
                        <template #append>
                            <img :src="verifyCodeUrl" class="verify-code" @click="updateVerifyCode()" />
                        </template>
                    </ElInput>
                </ElFormItem>

                <ElFormItem>
                    <ElCheckbox v-model="rememberMe" label="记住我"></ElCheckbox>
                </ElFormItem>

                <ElFormItem>
                    <ElButton class="w-full" size="default" type="primary" :loading="loading" @click="login()">
                        登录
                    </ElButton>
                </ElFormItem>
            </ElForm>
        </div>
    </div>
</template>

<style lang="scss">
.login-bg {
    position: fixed;
    height: 100%;
    left: 0;
    bottom: 0;
    z-index: -1;
}

.login-container {
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    position: absolute;
    display: flex;
    justify-items: center;
    justify-content: center;

    .login-box {
        display: flex;
        align-items: center;
        text-align: center;

        .login-form {
            width: 360px;

            .verify-code-row {
                .el-input-group__append {
                    padding: 0;
                }

                .verify-code {
                    height: 40px;
                }
            }
        }
    }
}
</style>